package com.xinke.query.web.query.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinke.query.common.exception.GaoSuQueryException;
import com.xinke.query.common.result.ResultCodeEnum;
import com.xinke.query.common.utils.GaoSuInfoUtils;
import com.xinke.query.model.entity.*;
import com.xinke.query.model.enums.FeedbackStatus;
import com.xinke.query.model.enums.QueryStatus;
import com.xinke.query.model.enums.QueryType;
import com.xinke.query.model.file.IdentificationFile;
import com.xinke.query.model.file.ResultFile;
import com.xinke.query.model.query.FeedbackQuery;
import com.xinke.query.model.query.GaoSuInfoQuery;
import com.xinke.query.model.vo.GaoSuInfoVo;
import com.xinke.query.web.query.mapper.GaoSuInfoMapper;
import com.xinke.query.web.query.mapper.UserQueryInfoMapper;
import com.xinke.query.web.query.service.GaoSuInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.List;

@Service
public class GaoSuInfoServiceImpl extends ServiceImpl<GaoSuInfoMapper, GaoSuInfo> implements GaoSuInfoService {

    @Autowired
    private GaoSuInfoMapper gaoSuInfoMapper;

    @Autowired
    private UserQueryInfoMapper userQueryInfoMapper;


    /**
     * 分页查询
     *
     * @param page
     * @param gaoSuInfoQuery
     * @return
     */
    @Override
    public IPage<GaoSuInfoVo> pageGaoSuInfoByQuery(IPage<GaoSuInfoVo> page, GaoSuInfoQuery gaoSuInfoQuery) {
        return gaoSuInfoMapper.pageGaoSuInfoByQuery(page, gaoSuInfoQuery);
    }

    /**
     * 根据id查询身份文件
     *
     * @param id
     * @return
     */
    @Override
    public IdentificationFile downloadFileById(Long id) {
        //判断记录是否存在
        QueryWrapper<GaoSuInfo> qw = new QueryWrapper<>();
        qw.eq("id", id);
        Long count = gaoSuInfoMapper.selectCount(qw);
        if (!count.equals(1)) {
            throw new GaoSuQueryException(710, "申请查询不存在");
        }
        //查询记录
        IdentificationFile file = gaoSuInfoMapper.selectFileInfoById(id);
        if (file == null || file.getFileContent() == null) {
            throw new GaoSuQueryException(710, "申请查询不存在");
        }
        return file;
    }

    /**
     * 根据applyId和queryType从文件系统中读取文件
     *
     * @param applyId
     * @param queryType
     * @return
     */
    @Override
    public File getResultByApplyIdAndQueryId(String applyId, Integer queryType) {
        return getFile(applyId, queryType);
    }

    /**
     * 用户文件系统中查询文件
     *
     * @param query
     * @return
     */
    @Override
    public File feedbackData(FeedbackQuery query) {
        //1.参数校验
        String md5 = query.getMd5();
        QueryType queryType = query.getQueryType();
        String applyId = query.getApplyId();

        if (md5.length() != 32 || applyId.length() != 36) {
            //参数检验失败
            throw new GaoSuQueryException(ResultCodeEnum.PARAM_VALIDATION_FAILED);
        }
        //2.根据apply_id从gaosu_info表查记录
        QueryWrapper<GaoSuInfo> qw = new QueryWrapper<>();
        qw.eq("apply_id", applyId);
        qw.eq("query_type", queryType);
        GaoSuInfo gaoSuInfo = gaoSuInfoMapper.selectOne(qw);
        //空值判断
        if (gaoSuInfo == null) {
            //申请查询不存在
            throw new GaoSuQueryException(ResultCodeEnum.APPLICATION_QUERY_NOT_EXIST);
        }
        //判断status
        QueryStatus status = gaoSuInfo.getStatus();
        if (status != QueryStatus.FINISHED) {
            //根据status不同返回不同类型的错误
            throw new GaoSuQueryException(GaoSuInfoUtils.getResultCodeEnum(status));
        }
        //判断feedbackStatus
        FeedbackStatus feedbackStatus = gaoSuInfo.getFeedbackStatus();
        if (feedbackStatus == FeedbackStatus.DOWNLOADING) {
            //已经在下载了
            throw new GaoSuQueryException(ResultCodeEnum.DATA_ALREADY_DOWNLOADING_DO_NOT_REPEAT_REQUEST);
        }
        //md5判断
        if (!md5.equals(gaoSuInfo.getMd5())) {
            //身份验证未匹配
            throw new GaoSuQueryException(ResultCodeEnum.IDENTITY_VERIFICATION_NOT_MATCH);
        }

        //3.开启查询
        File zipFile;
        GaoSuInfo updateInfo = new GaoSuInfo();
        updateInfo.setId(gaoSuInfo.getId());
        try {
            //修改feedbackStatus为1-下载中
            updateInfo.setFeedbackStatus(FeedbackStatus.DOWNLOADING);
            gaoSuInfoMapper.updateById(updateInfo);


            //根据apply_id 和 QueryType获取文件
            zipFile = getFile(applyId, queryType);

            //修改feedbackStatus为2-下载完成
            updateInfo.setFeedbackStatus(FeedbackStatus.DOWNLOADED);
            gaoSuInfoMapper.updateById(updateInfo);
        } catch (GaoSuQueryException e) {
            //若是查询结果为空，则直接抛出异常
            throw e;
        } catch (Exception e) {
            //若是其它异常，则返回下载失败
            //修改feedback为3-下载失败
            updateInfo.setFeedbackStatus(FeedbackStatus.DOWNLOAD_FAILED);
            gaoSuInfoMapper.updateById(updateInfo);
            throw new GaoSuQueryException(ResultCodeEnum.DATA_DOWNLOAD_FAILED);
        }

        //6.返回文件
        return zipFile;
    }


    /**
     * 1.根据queryType查询
     * 2.结果存入文件系统
     *
     * @param gaoSuInfo
     */
    @Override
    public void openQuery(GaoSuInfo gaoSuInfo) {
        try {
            //类型判断，执行三类查询
            QueryType queryType = gaoSuInfo.getQueryType();
            QueryJsonParams qj = gaoSuInfo.getQueryJsonparams();
            ResultFile resultFile = new ResultFile();
            if (queryType == QueryType.PASSDATA) {
                List<PassData> passDataList = gaoSuInfoMapper.selectPassData(qj);
                resultFile.setFileList(passDataList);
            }
            if (queryType == QueryType.ETCINFO) {
                List<PassPicData> passPicDataList = gaoSuInfoMapper.selectPassPicData(qj);
                resultFile.setFileList(passPicDataList);
            }
            if (queryType == QueryType.PASSPICDATA) {
                List<EtcInfo> etcInfoList = gaoSuInfoMapper.selectEtcInfo(qj);
                resultFile.setFileList(etcInfoList);
            }
            //无结果，抛出查询为空异常
            if (resultFile.getFileList().size() == 0) {
                //修改查询status为为完成
                updateStatusById(gaoSuInfo.getId(), QueryStatus.FINISHED);
                throw new GaoSuQueryException(ResultCodeEnum.DATA_QUERY_RESULT_EMPTY);
            }
            //若有结果，查询结果存入文件系统，修改status为2-查询成功
            //resultFile数据写入
            resultFile.setQueryType(gaoSuInfo.getQueryType());
            resultFile.setApplyId(gaoSuInfo.getApplyId());
            resultFile.setTotalBatchSize(resultFile.getFileList().size());
            //存入文件系统
            saveQueryFile(resultFile);
            //修改查询status为为完成
            updateStatusById(gaoSuInfo.getId(), QueryStatus.FINISHED);
        } catch (GaoSuQueryException e) {
            throw new GaoSuQueryException(ResultCodeEnum.DATA_QUERY_RESULT_EMPTY);
        } catch (Exception e) {
            //若查询失败，则修改status为3-查询失败
            updateStatusById(gaoSuInfo.getId(), QueryStatus.QUERYFAIL);
            //抛出异常，申请查询查询失败
            throw new GaoSuQueryException(ResultCodeEnum.APPLY_QUERY_QUERY_FAILED, e.getMessage());
        }
    }

    /**
     * 根据id修改status
     *
     * @param id
     * @param queryStatus
     */
    @Override
    public void updateStatusById(Long id, QueryStatus queryStatus) {
        GaoSuInfo gaoSuInfo = new GaoSuInfo();
        gaoSuInfo.setId(id);
        gaoSuInfo.setStatus(queryStatus);
        gaoSuInfoMapper.updateById(gaoSuInfo);
    }


    /**
     * 存入文件系统
     * todo：后期改造成文件系统 MINIO
     *
     * @param resultFile
     */
    @Override
    public void saveQueryFile(ResultFile resultFile) throws IOException {
        //1.将文件拆分成1000条一组。
        splitAndZip(resultFile, 1000);
        //2.转换成.json文件存入文件夹
        //3.将所有.json文件打包成.zip文件，最后一个文件夹下面只有一个zip包
        //TODO:调用splitAndZip方法
    }

    /**
     * 文件查询方法，走这一步说明文件已经准备就绪了，如果文件为空，则是查询结果为空
     * todo：后期改造成文件系统 MINIO
     *
     * @param applyId
     * @param queryType
     * @return
     */
    private File getFile(String applyId, Integer queryType) {
        //参数检验
        if (applyId != null && applyId.length() != 36) {
            throw new GaoSuQueryException(ResultCodeEnum.PARAM_VALIDATION_FAILED, "applyId格式错误");
        }
        if (queryType != null && !QueryType.contains(queryType)) {
            throw new GaoSuQueryException(ResultCodeEnum.PARAM_VALIDATION_FAILED, "queryType类型错误");
        }
        //拼接文件名TODO：需要增加日期文件夹 如2025.09.03
        StringBuilder sb = new StringBuilder();
        //包名
        sb.append("D:\\xinke\\gaosu_info_files\\").append(applyId).append("\\").append(queryType).append("\\");
        //文件名
        String fileName = applyId + "_" + queryType + ".zip";
        sb.append(fileName);

        //返回
        File zipFile = new File(sb.toString());
        //判断是否存在
        if (!zipFile.exists()) {
            throw new GaoSuQueryException(ResultCodeEnum.DATA_QUERY_RESULT_EMPTY);
        }
        return zipFile;
    }

    private File getFile(String applyId, QueryType queryType) {
        return getFile(applyId, queryType.getCode());
    }


//    /**
//     * 根据查询id查询批次信息
//     *
//     * @param gaosuInfoId
//     * @return
//     */
//    @Override
//    public Map<String, Long> getFileBatchInfoById(Long gaosuInfoId) {
//        //判断gaosuInfoId是否存在
//        QueryWrapper<GaoSuInfo> qw = new QueryWrapper<>();
//        qw.eq("id", gaosuInfoId);
//        Long count = gaoSuInfoMapper.selectCount(qw);
//        if (count == 0) {
//            throw new GaoSuQueryException(201, "id对应数据不存在");
//        }
//        //判断gaosuInfoId对应的数据是否已经存入
//        Integer status = gaoSuInfoMapper.selectStatusById(gaosuInfoId);
//        if (status == null) {
//            throw new GaoSuQueryException(201, "id对应数据不存在");
//        }
//
//        UserQueryInfo userQueryInfo = userQueryInfoMapper.seletBatchInfoById(gaosuInfoId);
//        //判断是否查到数据
//        if (userQueryInfo == null || userQueryInfo.getTotalCount() == null || userQueryInfo.getBatchCount() == null) {
//            throw new GaoSuQueryException(ResultCodeEnum.DATA_QUERY_RESULT_EMPTY);
//        }
//        Map<String, Long> batchInfo = new HashMap<>();
//        //总条数
//        Long totalCount = userQueryInfo.getTotalCount();
//        //总组数
//        Long batchCount = Long.valueOf(userQueryInfo.getBatchCount());
//        batchInfo.put("totalCount", totalCount);
//        batchInfo.put("batchCount", batchCount);
//        return batchInfo;
//    }
//
//    /**
//     * 根据gaosu_info表的id，批次号查询记录
//     *
//     * @param gaosuInfoId
//     * @param batchNum
//     * @return
//     */
//    @Override
//    public ResultFile getQueryFileByIdAndBatchNum(Long gaosuInfoId, Integer batchNum) {
//        ResultFile file = userQueryInfoMapper.selectFileByIdAndBatchNum(gaosuInfoId, batchNum);
//        //判断gaosuInfoId是否存在
//
//        //判断batchNum是否超出batchCount
//
//        //判断是否查到记录
//        if (file == null || file.getFileList() == null) {
//            throw new GaoSuQueryException(ResultCodeEnum.DATA_QUERY_RESULT_EMPTY);//未查到数据
//        }
//
//        return null;
//    }

}
